<?php

namespace App\Utility;

use EasySwoole\Component\Singleton;
use EasySwoole\HttpClient\Exception\InvalidUrl;
use EasySwoole\HttpClient\HttpClient;
use EasySwoole\Smtp\Exception\Exception;

class Sms
{
    use Singleton;

    /**
     * 计算参数签名
     * $params 请求参数
     * $secretKey secretKey
     */
    function gen_signature($secretKey, $params): string
    {
        ksort($params);
        $buff = "";
        foreach ($params as $key => $value) {
            if ($value !== null) {
                $buff .= $key;
                $buff .= $value;
            }
        }
        $buff .= $secretKey;
        return md5($buff);
    }

    /**
     * 将输入数据的编码统一转换成utf8
     * @params 输入的参数
     */
    function toUtf8($params, $internalStringCharset): array
    {
        $utf8s = array();
        foreach ($params as $key => $value) {
            $utf8s[$key] = is_string($value) ? mb_convert_encoding($value, "utf8", $internalStringCharset) : $value;
        }
        return $utf8s;
    }

    /**
     * 易盾短信发送在线检测请求接口简单封装
     * $params 请求参数
     */
    function check($params, $secretId, $businessId, $version, $secretKey, $apiTimeOut, $apiUrl)
    {
        $params["secretId"] = $secretId;
        $params["businessId"] = $businessId;
        $params["version"] = $version;
        $params["timestamp"] = sprintf("%d", round(microtime(true) * 1000));// time in milliseconds
        $params["nonce"] = sprintf("%d", rand()); // random int
        $params = $this->toUtf8($params, 'auto');
        $params["signature"] = $this->gen_signature($secretKey, $params);
        // var_dump($params);
        $options = array(
            'http' => array(
                'header' => "Content-type: application/x-www-form-urlencoded\r\n",
                'method' => 'POST',
                'timeout' => $apiTimeOut, // read timeout in seconds
                'content' => http_build_query($params),
            ),
        );
        $context = stream_context_create($options);
        $result = file_get_contents($apiUrl . "/sendsms", false, $context);
        if ($result === FALSE) {
            return array("code" => 500, "msg" => "file_get_contents failed.");
        } else {
            return json_decode($result, true);
        }
    }

    /**
     * @param $appid
     * @param $secret
     * @param $phone
     * @param $signName
     * @param $tplid
     * @param $code
     * @return mixed
     * @throws InvalidUrl
     */
    function sendSms($appid, $secret, $phone, $signName, $tplid, $code)
    {
        date_default_timezone_set('GMT');
        $tplParam = json_encode(['code' => $code]);
        $params = [
            'AccessKeyId' => $appid,                 // appid
            'Timestamp' => date('Y-m-d\TH:i:s'), //时间
            'SignatureMethod' => 'HMAC-SHA1',  //固定值
            'SignatureVersion' => '1.0',     //固定值
            'SignatureNonce' => uniqid(),  //随机码(这是PHP函数基于以微秒计的当前时间，生成一个唯一的ID)
            //'Signature' => ''
            'Format' => 'JSON',        //返回的数据类型(如果不传官方说默认JSON经测试是XML)
            //业务参数
            'Action' => 'SendSms',     //固定值不要更改
            'Version' => '2017-05-25',   //API的版本(固定值)
            'RegionId' => 'cn-hangzhou',  //API支持的RegionID(固定值)
            'PhoneNumbers' => $phone,        //接收号码
            'SignName' => $signName,    //签名
            'TemplateCode' => $tplid,       //模板id
            'TemplateParam' => $tplParam,    //短信模板变量替换JSON串，如$code

        ];
        //排序
        ksort($params);
        $str = '';
        foreach ($params as $k => $v) {
            $str .= urlencode($k) . '=' . urlencode($v) . '&';
        }
        $str = substr($str, 0, -1);//把最后一个'&'符号截取下去

        $str = str_replace(['+', '*', '%7E'], ['%20', '%2A', '~'], $str);//替换字符

        $new_str = 'GET&' . urlencode('/') . '&' . urlencode($str);//拼接新字符串

        $sign = base64_encode(hash_hmac('sha1', $new_str, $secret . '&', true));

        $sign = urlencode($sign);//生成签名
        $url = 'http://dysmsapi.aliyuncs.com/?Signature=' . $sign . '&' . $str;
        $client = new HttpClient($url);
        $client->setUrl($url);
        $response = $client->get();
        date_default_timezone_set('Asia/Shanghai');
        return $response->getBody();
    }
}